import 'dart:async';
import 'dart:convert';
import 'package:agora_rtm/agora_rtm.dart';
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:flutter/material.dart';
import 'package:crypto/crypto.dart';
import 'package:encrypt/encrypt.dart' as encrypt; // 使用别名导入
import 'package:gameplay_flutter/lib_basemodel/chat_room/chat/hb_message_type.dart';
import 'package:gameplay_flutter/lib_basemodel/chat_room/habibi-msg/hb_rtm_msg.dart';
import 'package:gameplay_flutter/lib_basemodel/chat_room/kh_chat_room_seat_user_model.dart';
import 'package:gameplay_flutter/m_chatroom/src/template/cars/user_join_animation_widget.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../../lib_basemodel/chat_room/chat/hb_rtm_message_type.dart';
import '../../../lib_basemodel/chat_room/habibi-msg/hb_rtm_message_detail_type.dart';
import '../../../lib_basemodel/chat_room/habibi-msg/hb_rtm_msg_detail.dart';
import '../../../lib_basemodel/chat_room/kh_chat_room_enter_model.dart';
import '../../../lib_basemodel/chat_room/kh_chat_room_model.dart';
import '../../../lib_basemodel/chat_room/kh_chat_room_seat_model.dart';
import '../../../lib_basemodel/chat_room/kh_room_check_model.dart';
import '../../../lib_basemodel/user/user.dart';
import '../../../lib_baseview/lib_baseview.dart';
import '../../../lib_baseview/utils/permission/permission_util.dart';
import '../../../lib_baseview/widget/dialogs.dart';
import '../../../lib_chat/chat/index.dart';
import '../../../lib_im/index.dart';
import '../../../lib_network/http_api.dart';
import '../../../lib_network/http_helper.dart';
import '../../../lib_rtc/mixin/rtm_message_mixin.dart';
import '../../../lib_rtc/rtc/rtm_manager.dart';
import '../../../lib_runtime/logger.dart';
import '../../../lib_user/user_manager.dart';
import '../config/room_constant.dart';
import '../doufeng/room_main/doufeng_page_model_mixin.dart';
import '../input/item_style.dart';
import '../msg/room_msg.dart';
import '../private_chat/gift/gift_page.dart';
import '../template/barrage/barrage_list_model.dart';
import '../template/music/model/room_music_center_controller.dart';
import 'chat_room_leaf_interface.dart';
import 'room_page.dart';

class RoomPageModel extends ChatRoomChangeNotifier
    with DoufengPageModelMixin, RtmMessageMixin {
  GlobalKey<State> mainKey = GlobalKey();

  KHChatRoomEnterModel roomEnterModel = KHChatRoomEnterModel();

  @override
  RtmClient get rtmClient => RtmManager.instance.rtmClient;

  /// 房间号
  late String roomNumber;

  // RtcUserRole get currentRoomUserType =>
  //     roomModel.channel?.role ?? RtcUserRole.Guest;

  // RoomType get roomType =>
  //     roomModel.channel?.roomTypeObj.type ?? RoomType.ORDER_SING;

  // /// 房主右右下角是否展示上麦列表
  // bool _micListEnabled = false;
  // bool get isMicListEnabled => _micListEnabled;
  // void setMicListEnabled() {
  //   _micListEnabled = !_micListEnabled;
  //   notifyListeners(); // 如果使用 ChangeNotifier
  // }

  /// 申请上麦列表
  List<HbRtmMsg?>? applyMicList;

  User? get currUser => UserManager.instance.currentUser;

  /// 麦克风是否开启
  bool get onMic => roomModel.isMicOn;

  /// 是否是房主，进入房间后根据当前返回房主信息和当前的用户id比较
  bool? get roomOwner =>
      roomEnterModel.chatRoomModel!.userInfo?.userId == currUser?.id;

  /// 是否是房主

  int get currentMicSeatPosition => 0;

  // bool get isCurrUserMicOn => roomModel.isMicOn;

  bool isShowingEndDrawer = false;
  late BarrageListModel barrageListModel;

  // bool get isCurrUserInMicQueue =>
  //     roomModel.channel?.waitQueue
  //         .map((e) => e.user.id.toInt())
  //         .contains(currUser?.id) ??
  //     false;

  bool get isCurrUserInMicQueue => false;
  AnimationController? userJoinAnimationController;
  late Animation animation;
  //进房用户数据 用于显示进房提示
  // List<RoomUserJoin> joinUserList = [];

  //开启房间列表侧边栏
  updateIsShowingEndDrawer(bool isOpen) {
    isShowingEndDrawer = isOpen;
    notifyListeners();
  }

  //初始化礼物动画controller(由于需要SingleTickerProviderStateMixin，因此在initState调用)
  initGiftAnimationController(
      SingleTickerProviderStateMixin singleTickerProviderStateMixin,
      BuildContext context) {
    userJoinAnimationController = AnimationController(
        vsync: singleTickerProviderStateMixin,
        duration: const Duration(milliseconds: 2500))
      ..addStatusListener((status) {
        RLog.d('joinAnimationStatus:$status');
        if (status == AnimationStatus.completed) {
          joinRoomAnimationComplete();
        }
      });

    TweenSequence tweenSequence = TweenSequence([
      TweenSequenceItem(tween: Tween<double>(begin: 0.0, end: 1.0), weight: 2),
      TweenSequenceItem(tween: Tween<double>(begin: 1.0, end: 1.0), weight: 8),
    ]);
    animation = tweenSequence.animate(userJoinAnimationController!);
  }

  AppLifecycleState cycleState = AppLifecycleState.resumed;

  /// 用户进入房间动画
  // void userJoinRoomAddItem(RoomUserJoin message) {
  //   RLog.i('userJoinRoomAddItem:$message');
  //   if (cycleState == AppLifecycleState.paused) {
  //     return;
  //   }
  //   if (!message.user.hasCar()) {
  //     return;
  //   }
  //   if (userJoinAnimationController?.status == AnimationStatus.dismissed) {
  //     RLog.i('userJoinAnimationController:forward');
  //     userJoinAnimationController?.forward();
  //   }
  //   joinUserList.add(message);
  //   notifyListeners();
  // }

  void joinRoomAnimationComplete() async {
    RLog.d('joinRoomAnimationComplete');
    userJoinAnimationController?.reset();
    // if (joinUserList.isNotEmpty) {
    //   joinUserList.removeAt(0);
    //   if (joinUserList.isNotEmpty) {
    //     userJoinAnimationController?.forward();
    //   }
    // }
    notifyListeners();
  }

  bool hasInitData = false;

  /// 标记是否请求过进入房间的四大接口
  bool hasRequestRoomData = false;
  //进房初始化流程
  initData(
      /*JoinChannelRsp joinChannelRsp, {JoinSource? joinSource} */ String
          roomNo) async {
    roomNumber = roomNo;

    if (hasInitData) return;

    // _setupRtmListener();
    // 通过Manager添加监听（演示Mixin的两种使用方式）
    RtmManager.instance.addRtmMessageListener(_handleMessage);

    barrageListModel = BarrageListModel((context, user) {
      // RoomPersonalDataWidget.show(context, channel, user);
    });

    await fetchRoomBaseData(roomNo);

    // 更新room model
    roomModel.joinChannel(this);

    barrageListModel
        .setChannelId(roomEnterModel.roomCheckBeanModel?.channel ?? 0);
    barrageListModel.channel =
        (roomEnterModel.roomCheckBeanModel?.channel ?? 0).toString();
    // barrageListModel.enable = channel?.freePublicChat ?? false;
    barrageListModel.enable = false;

    // /// 获取公屏历史消息
    getHistoryMsg(roomNo);
    // 后台播放
    // FlutterCommon().setAudioSessionPlayBack(true);

    /// 发送用户进入房间消息
    sendUserJsonMessage();

    hasInitData = true;
    notifyListeners();
  }

  /// ===========================================================================================
  /// ===========================================================================================
  /// ==  进入房间 四大接口
  /// ===========================================================================================
  /// ===========================================================================================
  Future fetchRoomBaseData(String roomNo) async {
    showLoadingDialog();

    /// 获取下列数据
    /// 获取房间基础信息
    /// 获取房间基础玩法
    /// 请求房间麦位
    /// 额外信息

    await Future.wait([
      fetchRoomEnterExt(roomNo),
      fetchRoomSeat(roomNo),
      // fetchRoomGame(roomNo),
      // fetchRoomExtraInfo(roomNo),
    ]).whenComplete(() {
      log("请求房间基础4大接口");
      hasRequestRoomData = true;
      notifyListeners();
      dismissLoadingDialog();
    }).onError((error, stackTrace) {
      log('请求房间基础4大接口err: $error');
      log('请求房间基础4大接口err: \n $stackTrace');
      return [];
    });
    dismissLoadingDialog();
  }

  /// 进入房间
  Future<bool> fetchRoomEnterExt(String roomNo) async {
    try {
      // 获取当前时间戳（秒）
      int timestampInSeconds = DateTime.now().millisecondsSinceEpoch ~/ 1000;

      var response = await HttpHelper.instance().post(
        HttpApi.voiceRoomEnterExt,
        body: {"roomNo": roomNo, "timestamp": timestampInSeconds},
      );

      if (!response.isSuccess) {
        throw Exception();
      } else {
        KHChatRoomModel tmpChatRoomModel =
            KHChatRoomModel.fromJson(response.result);

        roomEnterModel.chatRoomModel = tmpChatRoomModel;

        if (tmpChatRoomModel.roomTokenBean != null) {
          /// 设置房间行令相关
          Map<String, dynamic> roomTokenMap = decryptRoomEnterCheckData(
              tmpChatRoomModel.roomTokenBean ?? '',
              timestampInSeconds.toString());

          roomEnterModel.roomCheckBeanModel =
              KHRoomCheckModel.fromJson(roomTokenMap);
        }

        print('rtc-->:${roomEnterModel.roomCheckBeanModel?.rtcToken}');
        print('rtm-->:${roomEnterModel.roomCheckBeanModel?.rtmToken}');

        // notifyListeners();
        return true;
      }
    } catch (e) {
      print('${e}');
      throw Exception(e);
    }
  }

  /// 请求房间麦位
  Future<bool> fetchRoomSeat(String roomNo) async {
    try {
      var response = await HttpHelper.instance().post(
        HttpApi.roomMicAll,
        body: {"roomNo": roomNo},
      );

      if (!response.isSuccess) {
        throw Exception();
      } else {
        try {
          List<KHChatRoomSeatModel?> tmpList = [];
          for (Map<String, dynamic> dict in response.result['roomMicList']) {
            KHChatRoomSeatModel? seatModel = KHChatRoomSeatModel.fromJson(dict);
            tmpList.add(seatModel);
          }
          roomEnterModel.micList = tmpList;

          if (hasRequestRoomData) notifyListeners();
        } catch (e) {
          print('$e');
        }
        return true;
      }
    } catch (e) {
      print('$e');
      throw Exception(e);
    }
  }

  /// 请求房间基础玩法
  Future<bool> fetchRoomGame(String roomNo) async {
    try {
      var response = await HttpHelper.instance().post(
        HttpApi.commonGame,
        body: {"roomNo": roomNo},
      );

      if (!response.isSuccess) {
        throw Exception();
      } else {
        print('');
        // chatRoomModel = KHChatRoomModel.fromJson(response.result);
        notifyListeners();
        return true;
      }
    } catch (e) {
      throw Exception(e);
    }
  }

  /// 请求房间 额外信息
  Future<bool> fetchRoomExtraInfo(String roomNo) async {
    try {
      var response = await HttpHelper.instance().post(
        HttpApi.roomEextraInfo,
        body: {"roomNo": roomNo, 'riskPoint': 0},
      );

      if (!response.isSuccess) {
        throw Exception();
      } else {
        print('');
        // chatRoomModel = KHChatRoomModel.fromJson(response.result);
        notifyListeners();
        return true;
      }
    } catch (e) {
      print('$e');

      throw Exception(e);
    }
  }

  /// ===========================================================================================
  /// ===========================================================================================
  /// ==  进入房间 四大接口  结束
  /// ===========================================================================================
  /// ===========================================================================================

  Map<String, dynamic> decryptRoomEnterCheckData(String data, String timeStr) {
    String keyStr = '';
    if (timeStr.length >= 8) {
      keyStr += timeStr[0];
      keyStr += timeStr[2];
      keyStr += timeStr[5];
      keyStr += timeStr[7];
    }

    // 计算 MD5 哈希值
    var bytes = utf8.encode(keyStr);
    var digest = md5.convert(bytes);
    String md5Str = digest.toString();
    String aesKeyStr = md5Str.substring(0, 16);

    // 创建 AES 解密器
    final key = encrypt.Key.fromUtf8(aesKeyStr); // 使用别名调用 Key
    final iv = encrypt.IV.fromLength(16); // 使用别名调用 IV
    final encrypter = encrypt.Encrypter(
        encrypt.AES(key, mode: encrypt.AESMode.ecb)); // 使用别名调用相关类

    // 解密数据
    try {
      final encrypted = encrypt.Encrypted.fromBase64(data); // 使用别名调用 Encrypted
      String jsonStr = encrypter.decrypt(encrypted, iv: iv);

      // 解析 JSON 字符串
      Map<String, dynamic> val = json.decode(jsonStr);
      return val;
    } catch (e) {
      return {};
    }
  }

  disposePageAndData() async {
    RoomPage.pop();
    await roomModel.release();
    RtmManager.instance.removeRtmMessageListener(_handleMessage);
    // FlutterCommon().setAudioSessionPlayBack(false);
  }

  ///发送麦上表情公屏消息
  sendMicImgMsg(String? imgUrl) {
    if (imgUrl?.isEmpty ?? true) return;
    // ChatContent chatContent = ChatContent(
    //     showItem: [ShowItem(style: ItemStyle.icon, url: imgUrl, size: 30)]);
    // sendChatMsg(SendToRoomReq(chat: chatContent, toRoomId: channel?.channelId));
  }

  /// 发送用户进入房间消息
  // UserJoinAnimationWidget

  sendUserJsonMessage() {
    HbRtmMsg rtmMsg = HbRtmMsg()
      ..type = HBMessageType.chatRoomOpenMsg
      ..rtmType = HBRtmMessageType.rtmSmallMessageTypeUserJoin
      ..msg = HbRtmMsgDetail()
      ..msg?.message = 'Join Room'
      ..msg?.nickName = currUser?.nickname
      ..msg?.messageType = HBRtmMessageDetailType.text;

    RoomMsg roomeMsg = RoomMsg(rtmMsg: rtmMsg);
    barrageListModel.addMsg(roomeMsg);

    String jsonStr = json.encode(rtmMsg.toJson());
    RtmManager.instance.publish(jsonStr);
  }

  /// 发送文本消息
  sendUserInputTextMessage(String text,
      {ItemStyle itemStyle = ItemStyle.text,
      String? extra,
      RoomMsg? quoteMsg}) async {
    // 假设已经有一个User实例表示发送者
    User? senderUser = UserManager.instance.currentUser;

    /// 发送rtm消息
    HbRtmMsg rtmMsg = HbRtmMsg()
      ..rtmType = HBRtmMessageType.rtmSmallMessageTypeText
      ..msg = HbRtmMsgDetail()
      ..msg?.headPortraitsUrl = senderUser?.headPortraitsUrl
      ..msg?.message = text
      ..msg?.roomNo = roomNumber
      ..msg?.messageType = HBRtmMessageDetailType.text
      ..msg?.nickName = senderUser?.nickname
      ..msg?.account = (senderUser?.id).toString();

    String jsonStr = json.encode(rtmMsg.toJson());
    RtmManager.instance.publish(jsonStr);

    /// 公屏插入本地消息
    RoomMsg roomeMsg = RoomMsg(rtmMsg: rtmMsg);
    barrageListModel.addMsg(roomeMsg);

    /// 公屏消息这里是3
    rtmMsg.type = HBMessageType.chatRoomOpenMsg;
    String jsonSocketStr = json.encode(rtmMsg.toJson());
    roomModel.roomSocket?.sendChatMsg(jsonSocketStr);
  }

  /// socket 消息组装
  /// tmpText 要发送的消息文本
  // void socketMessageAssembly(String text,
  //     {ItemStyle itemStyle = ItemStyle.text,
  //     String? extra,
  //     RoomMsg? quoteMsg}) {
  //   try {
  //     ChatContent chatContent = ChatContent(
  //         showItem: [ShowItem(style: itemStyle, text: text, extra: extra)]);
  //     if (quoteMsg != null) {
  //       quoteMsg.clearQuoteMsg(); // 防止嵌套
  //       chatContent.quoteMsg = quoteMsg.msg;
  //     }
  //     sendChatMsg(
  //         SendToRoomReq(chat: chatContent, toRoomId: channel?.channelId));
  //   } catch (e, r) {
  //     print("SocketMsg 消息格式错误 error $e");
  //     print("SocketMsg 消息格式错误 stack $r");
  //   }
  // }

  // /// socket 发送公屏消息
  // void sendChatMsg(SendToRoomReq msgData) => roomModel.sendChatMsg(msgData);

  void log(String msg) => RLog.d('RoomPageModel: $msg');

  Future<void> realDispose() async {
    try {
      // await leaveCompanion(rootProxyModel.prtType);

      //注销动画controller
      userJoinAnimationController?.dispose();

      // 停止音乐
      // PlayManager.instance.stopPlay();
      Get.delete<RoomMusicCenterController>(force: true);
    } catch (e) {
      RLog.d('Catch exception: $e');
    }
  }

  @override
  observeMessage(int messageId, data) {
    if (messageId == RoomConstant.MESSAGE_ID_BACKGROUND) {
      notifyListeners();
    } else if (messageId == RoomConstant.MESSAGE_ID_JOIN_MIC) {
      // joinMic(data as MicSeatInfo);
    } else if (messageId == RoomConstant.MESSAGE_ID_QUIT_MIC) {
      // quitMic(data as MicSeatInfo);
    } else if (messageId == RoomConstant.MESSAGE_ID_CHANGE_PRIVACY) {
      notifyListeners();
    } else if (messageId == RoomConstant.MESSAGE_ID_CHANGE_INFORMATION) {
      notifyListeners();
    } else if (messageId == RoomConstant.MESSAGE_ID_CHANGE_TEMPLATE) {
      // if ((channel?.template.gameId.toInt() ?? 0) > 0) {
      //   initGame();
      // } else {
      notifyListeners();
      // }
    } else if (messageId == RoomConstant.MESSAGE_ID_CHANGE_FREE_PUB) {
      notifyListeners();
    }
  }

  changeMicStatus() async {
    log('Click mute icon, change mic status with current: $onMic');
    if (onMic) {
      await closeMic();
      roomModel.isMicOn = false;
    } else {
      await openMic();
      roomModel.isMicOn = true;
    }
    notifyListeners();
  }

  _openModalBottomSheet(BuildContext context, WidgetBuilder builder) {
    showModalBottomSheet(
      isScrollControlled: true,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(24),
          topRight: Radius.circular(24),
        ),
      ),
      context: context,
      builder: builder,
    );
  }

  openProgramList(BuildContext context) {
    // _openModalBottomSheet(context, (context) => ProgramListPage());
  }

  openChooseBackgroundDialog(BuildContext context) {
    // _openModalBottomSheet(context, (context) => ChooseBackgroundPage());
  }

  clickRoomGift(BuildContext context) {
    // var userList = <GiftUser>[];
    // if (channel != null) {
    //   var hasOwner = false; // 房主是否在打赏列表
    //   for (var element in channel!.broadcaster) {
    //     if (element.hasUser() == false || element.user.id == currUser?.id) {
    //       continue;
    //     }
    //     if (element.user.id == channel?.owner.id) hasOwner = true;

    //     var user = GiftUser()
    //       ..userId = element.user.id.toString()
    //       ..nickName = element.user.nickname
    //       ..avatar = element.user.avatar;
    //     userList.add(user);
    //   }

    //   // CP房，将房主加到打赏列表
    //   if ((roomModel.channelExt.value?.hasCpInfo() ?? false) &&
    //       !hasOwner &&
    //       currUser?.id != channel?.owner.id) {
    //     var user = GiftUser()
    //       ..userId = channel?.owner.id.toString()
    //       ..nickName = channel?.owner.nickname
    //       ..avatar = channel?.owner.avatar;
    //     userList.insert(0, user);
    //   }
    // }
    // GiftPage.show(context, GiftScene.chatroom, userList, channel);

    if (UserManager.instance.currentUser != null) {
      // 过滤 data 不为 null 的对象
      final micListUser = roomEnterModel.micList
          ?.where((obj) => obj?.micUser != null) // 过滤条件
          .toList(); // 转换为列表

      GiftPage.show(context, micListUser, roomNumber,
          giftCallBack: (list, giftModel, count) {
        /// 显示飘屏
        final objUrl = giftModel?.objectGifUrl;
        if (objUrl != null) showGiftFloatingScreen(context, objUrl);

        /// 公平发送礼物消息
        sendUserGiftMessage(list, giftModel, count);
      });
    }
  }

  /// 显示礼物飘屏
  void showGiftFloatingScreen(BuildContext context, String obj) {
    showDialog(
      context: context,
      barrierColor: Colors.transparent,
      barrierDismissible: false,
      builder: (_) => MessageGiftSvga(
        obj,
        callback: () {
          if (Navigator.of(context).canPop()) {
            Navigator.of(context).pop();
          }
        },
      ),
    );
  }

  /// 发送礼物消息
  /// micUser:礼物接收者
  /// giftModel：送的礼物
  /// count：赠送的数量
  sendUserGiftMessage(List micUser, ImGitfModel? giftModel, int count) async {
    /// 如果麦上有多少个用户，那么这里在公屏上发送多少次消息
    for (int i = 0; i < micUser.length; i++) {
      // 当前用户是发送者
      User? senderUser = UserManager.instance.currentUser;
      KHChatRoomSeatModel tmpReceiveUser = micUser[i];

      /// 发送rtm消息
      HbRtmMsg rtmMsg = HbRtmMsg()
        ..rtmType = HBRtmMessageType.rtmSmallMessageTypeReward
        ..msg = HbRtmMsgDetail()
        ..msg?.headPortraitsUrl = senderUser?.headPortraitsUrl
        ..msg?.giftCount = count
        ..msg?.receiveNickName = tmpReceiveUser.micUser?.nickname
        ..msg?.objectVapUrl = giftModel?.objectVapUrl
        ..msg?.objectGifUrl = giftModel?.objectGifUrl
        ..msg?.messageType = HBRtmMessageDetailType.gift
        ..msg?.objectUrl = giftModel?.objectUrl
        ..msg?.roomNo = roomNumber
        ..msg?.nickName = senderUser?.nickname
        ..msg?.account = (senderUser?.id).toString();

      // ChatContent chatContent = ChatContent()
      //   ..type = HBMessageType.gift
      //   ..senderUser = senderUser
      //   ..receiveUser = tmpReceiveUser
      //   ..message?.time = DateTime.now().millisecondsSinceEpoch
      //   ..message?.data?.count = count
      //   ..message?.data?.giftModel = giftModel;

      /// 发送消息
      // roomModel.roomRtcRtm?.publishRtm(rtmMsg.toJson());
      String jsonStr = json.encode(rtmMsg.toJson());
      RtmManager.instance.publish(jsonStr);

      /// 本地公屏 插入消息
      RoomMsg roomeMsg = RoomMsg(rtmMsg: rtmMsg);
      barrageListModel.addMsg(roomeMsg);
    }
  }

  ///打开麦克风
  Future<void> openMic() => roomModel.openMic();

  ///关闭麦克风
  Future<void> closeMic() => roomModel.closeMic();

  void updateRoomMicInfo() {}

  /// 点击下麦
  void downMicAuto(BuildContext context, String? roomNo, int position) async {
    User? tmpUser = UserManager.instance.currentUser;
    var response = await HttpHelper.instance().post(
      HttpApi.roomMicHoldDown,
      body: {
        "roomNo": roomNo, // 房间号
        'userId': tmpUser!.id, // 用户id
        'index': position, // 麦位索引
        'status': -1, // 下麦
      },
    );

    if (!response.isSuccess) {
      throw Exception();
    } else {
      /// 发送下麦消息
      HbRtmMsg msg = HbRtmMsg()
        ..rtmType = HBRtmMessageType.rtmSmallMessageTypeUserDown
        ..msg = HbRtmMsgDetail()
        ..msg?.account = tmpUser.id.toString()
        ..msg?.headPortraitsUrl = tmpUser.headPortraitsUrl
        ..msg?.roomNo = roomNumber
        ..msg?.nickName = tmpUser.nickname;

      String jsonStr = json.encode(msg);
      RtmManager.instance.publish(jsonStr);

      roomModel.roomRtcRtm?.setAudience();
      roomModel.roomRtcRtm?.closeMic();
      roomModel.notify();

      /// 主播主动刷一下自己的麦位列表
      fetchRoomSeat(roomNumber);
    }
  }

  /// 点击上麦
  Future<void> joinMicAuto(BuildContext context, {int? position}) async {
    if (await PermissionUtil.checkAndRequestPermissions(
            context, Permission.microphone) !=
        PermissionStatus.granted) {
      return;
    }

    if (roomEnterModel.chatRoomModel?.userInfo?.roomRole == 1) {
      roomRoleHoldUpMic(position: position);
    } else {
      var response = await HttpHelper.instance().post(
        HttpApi.roomMicUp,
        body: {
          "roomNo": roomNumber,
          'index': position,
          'curOpType': 1,
          'needPushTypes': 1,
        },
      );

      if (!response.isSuccess) {
        showToast('${response.result['msg']}');
      } else {
        showToast('申请上麦成功');
        User? tmpUser = UserManager.instance.currentUser;

        HbRtmMsg msg = HbRtmMsg()
          ..rtmType = HBRtmMessageType.rtmSmallMessageTypeApplySeat
          ..msg = HbRtmMsgDetail()
          ..msg?.account = tmpUser?.id.toString()
          ..msg?.headPortraitsUrl = tmpUser?.headPortraitsUrl
          ..msg?.roomNo = roomNumber
          ..msg?.nickName = tmpUser?.nickname;

        String jsonStr = json.encode(msg);

        RtmManager.instance.publish(jsonStr);
      }
    }
  }

  roomRoleHoldUpMic({int? position}) async {
    /// 遍历本地麦位列表
    int? tmpIndex = findEmptyMic();

    if (tmpIndex == null) return;

    var response = await HttpHelper.instance().post(
      HttpApi.roomMicHoldUp,
      body: {
        "roomNo": roomNumber,
        'userId': UserManager.instance.currentUser!.id,
        'index': tmpIndex,
      },
    );

    if (!response.isSuccess) {
      throw Exception();
    } else {
      HbRtmMsg? tmpMsg = HbRtmMsg()
        ..rtmType = HBRtmMessageType.rtmSmallMessageTypeUserUpper
        ..msg = HbRtmMsgDetail()
        ..msg?.roomNo = roomNumber
        ..msg?.account = UserManager.instance.currentUser!.id.toString();
      String jsonStr = json.encode(tmpMsg);
      RtmManager.instance.publish(jsonStr);
    }

    /// 设置自己成为主播
    roomModel.roomRtcRtm?.openMic();

    /// 主播主动刷一下自己的麦位列表
    fetchRoomSeat(roomNumber);
  }

  /// 设置用户上麦
  /// 设置用户上麦，这里需要遍历麦位列表，为空直接设置上去
  /// index:主播允许的上麦列表中的index
  holdUpMic(int index) async {
    /// 遍历本地麦位列表
    int? tmpIndex = findEmptyMic();

    if (tmpIndex == null) return;

    /// tmpIndex 代表的麦位为空
    HbRtmMsg? applyUser = applyMicList?[index];
    if (applyUser != null) {
      var response = await HttpHelper.instance().post(
        HttpApi.roomMicHoldUp,
        body: {
          "roomNo": applyUser.msg?.roomNo,
          'userId': applyUser.msg?.account,
          'index': tmpIndex,
        },
      );

      if (!response.isSuccess) {
        throw Exception();
      } else {
        // showToast('申请上麦成功');
        /// 主播同意上麦，发送rtm为3的消息。直播间所有的用户收到此消息后刷新自己的麦位
        HbRtmMsg? tmpMsg = HbRtmMsg()
          ..rtmType = HBRtmMessageType.rtmSmallMessageTypeUserUpper
          ..msg = HbRtmMsgDetail()
          ..msg?.roomNo = applyUser.msg?.roomNo
          ..msg?.account = applyUser.msg?.account;
        String jsonStr = json.encode(tmpMsg);
        RtmManager.instance.publish(jsonStr);
      }

      /// 清除上麦列表的指定数据
      applyMicList?.removeAt(index);

      /// 主播主动刷一下自己的麦位列表
      fetchRoomSeat(applyUser.msg!.roomNo!);
    }
  }

  /// 获取当前的空麦位，并且返回第一个空麦位数据
  int? findEmptyMic() {
    if (roomEnterModel.micList == null) {
      return null;
    }
    int? firstEmptyIndex = roomEnterModel.micList!
        .indexWhere((element) => element?.micUser == null);
    if (firstEmptyIndex != -1) {
      return firstEmptyIndex;
    }
    return null;
  }

  openMicWaitingListPage(BuildContext context) {
    // _openModalBottomSheet(context, (context) => MicWaitingListPage());
  }

  // Future<void> updateChannel(Channel? newChannel) async {
  //   if (newChannel == null) return;

  //   roomModel.channel = newChannel;
  //   roomModel.notifyListeners();
  // }

  // changeUserRole(
  //     $fixnum.Int64 uid, RtcUserRole role, VoidCallback successCallback) async {
  //   var updateRule = ChannelChangeRole.create()
  //     ..uid = uid
  //     ..role = role;
  //   var result = await RtcApi.instance.updateChannel(ChannelUpdate.create()
  //     ..channel = roomModel.channel!.channelId
  //     ..changeRole = updateRule);
  //   if (result.isSuccess) {
  //     successCallback();
  //   }
  // }

  startAuditionVoice($fixnum.Int64? userId) async {
    if (userId == null) return;

    // ChannelUpdate req = ChannelUpdate.create()..channel = channel!.channelId;
    // req.changeAudition = ChannelChangeAudition.create()..uid = userId;

    // await handleRsp(() => RtcApi.instance.updateChannel(req));
  }

  stopAuditionVoice($fixnum.Int64? userId) async {
    if (userId == null) {
      return;
    }
    // ChannelUpdate req = ChannelUpdate.create()..channel = channel!.channelId;
    // req.changeAudition = ChannelChangeAudition.create()..uid = $fixnum.Int64(0);

    // await handleRsp(() => RtcApi.instance.updateChannel(req));
  }

  /// 获取房间历史消息
  Future<void> getHistoryMsg(String roomNo) async {
    HbRtmMsg rtmMsg = HbRtmMsg()
      ..type = HBMessageType.chatRoomOpenMsg
      ..rtmType = HBRtmMessageType.rtmSmallMessageTypeText
      ..msg = HbRtmMsgDetail()
      // msg?.messageType
      ..msg?.message = roomEnterModel.chatRoomModel!.roomInfo?.roomMsg
      ..msg?.messageType = HBRtmMessageDetailType.safeMsg;

    RoomMsg roomeMsg = RoomMsg(rtmMsg: rtmMsg);
    barrageListModel.addMsg(roomeMsg);

    try {
      var response = await HttpHelper.instance().post(
        HttpApi.roomHistory,
        body: {"roomNo": roomNo},
      );

      if (!response.isSuccess) {
        throw Exception();
      } else {
        for (Map<String, dynamic> dict in response.result) {
          HbRtmMsgDetail? detailModel = HbRtmMsgDetail.fromJson(dict);
          HBRtmMessageType? rtmType;
          if (detailModel.messageType == HBRtmMessageDetailType.text) {
            rtmType = HBRtmMessageType.rtmSmallMessageTypeText;
          } else if (detailModel.messageType == HBRtmMessageDetailType.gift) {
            rtmType = HBRtmMessageType.rtmSmallMessageTypeReward;
          }
          HbRtmMsg rtmMsg = HbRtmMsg()
            ..type = HBMessageType.chatRoomOpenMsg
            ..rtmType = rtmType
            ..msg = detailModel;

          RoomMsg roomeMsg = RoomMsg(rtmMsg: rtmMsg);
          barrageListModel.addMsg(roomeMsg);
        }

        notifyListeners();
      }
    } catch (e) {
      print('$e');

      throw Exception(e);
    }
  }

  ///是否正在试音
  bool get inAudition => false;

  /// 房间设置相关函数 ------
  roomToolsShare() {}
  roomToolsEdit() {}
  roomToolsMember() {}
  roomToolsNumber() {}
  roomToolsWallpaper() {}
  roomToolsMusic() {}
  roomToolsPrivacy() {}
  roomToolsLock() {}
  roomToolsPublicScreen() {}
  roomToolsMode() {}
  roomToolsEarMonitoring() {}

  Future<void> _handleMessage(MessageEvent event) async {
    print(
        'recieved a message from channel: ${event.channelName}, channel type : ${event.channelType}');
    print(
        'message content: ${utf8.decode(event.message!)}, custome type: ${event.customType}');

    String str = utf8.decode(event.message!);

    // 将字符串转为 Map
    Map<String, dynamic> dataMap = jsonDecode(str);

    HbRtmMsg rtmMsg = HbRtmMsg.fromJson(dataMap);

    /// 申请上麦
    if (rtmMsg.rtmType == HBRtmMessageType.rtmSmallMessageTypeApplySeat) {
      // 更新UI等操作
      /// 申请上麦列表
      applyMicList ??= [];

      bool isDuplicate = applyMicList!.any((existingMsg) =>
          existingMsg != null &&
          existingMsg.msg?.account == rtmMsg.msg?.account);

      if (!isDuplicate) {
        applyMicList?.add(rtmMsg);
      }

      notifyListeners();
    } else if (rtmMsg.rtmType ==
        HBRtmMessageType.rtmSmallMessageTypeUserUpper) {
      /// 请求房间数据
      if (rtmMsg.msg?.roomNo != null) {
        fetchRoomSeat(rtmMsg.msg!.roomNo!);
      }

      /// 设置当前用户成主播
      if (rtmMsg.msg?.account ==
          (UserManager.instance.currentUser?.id).toString()) {
        await openMic();
      }
    } else if (rtmMsg.rtmType == HBRtmMessageType.rtmSmallMessageTypeUserDown) {
      /// 请求房间数据
      if (rtmMsg.msg?.roomNo != null) {
        fetchRoomSeat(rtmMsg.msg!.roomNo!);
      }
    } else if (rtmMsg.rtmType == HBRtmMessageType.rtmSmallMessageTypeText) {
      /// 公屏插入本地消息
      RoomMsg roomeMsg = RoomMsg(rtmMsg: rtmMsg);
      barrageListModel.addMsg(roomeMsg);
    } else if (rtmMsg.rtmType == HBRtmMessageType.rtmSmallMessageTypeReward) {
      /// 展示飘屏
      final objUrl = rtmMsg.msg?.objectGifUrl;
      if (objUrl != null) showGiftFloatingScreen(Get.context!, objUrl);

      /// 公屏插入本地消息
      RoomMsg roomeMsg = RoomMsg(rtmMsg: rtmMsg);
      barrageListModel.addMsg(roomeMsg);
    } else if (rtmMsg.rtmType == HBRtmMessageType.rtmSmallMessageTypeUserJoin) {
      RoomMsg roomeMsg = RoomMsg(rtmMsg: rtmMsg);
      barrageListModel.addMsg(roomeMsg);
    }
  }
}

class RoomAnimationData {
  String url;
  User? userJoinUser;

  RoomAnimationData(this.url, {this.userJoinUser});
}
